import os
import re
import shutil
import hashlib
from datetime import datetime
from typing import List, Pattern
import redis


# 从源目录下，查找抖音等视频文件，保存到目标目录下
# 用redis缓存重复文件的md5
class VideoFileOrganizer:
    def __init__(self, source_dir: str, target_dir: str, name_patterns: List[str],
                 video_extensions: List[str], move_files: bool = False,
                 redis_host: str = 'localhost', redis_port: int = 6379, redis_db: int = 0):
        self.source_dir = source_dir
        self.target_dir = target_dir
        self.name_patterns = [re.compile(pattern) for pattern in name_patterns]
        self.video_extensions = video_extensions
        self.move_files = move_files
        self.redis_client = redis.Redis(host=redis_host, port=redis_port, db=redis_db)

    def is_video_file(self, filename: str) -> bool:
        return any(filename.lower().endswith(ext) for ext in self.video_extensions)

    def matches_name_pattern(self, filename: str) -> bool:
        return any(pattern.search(filename) for pattern in self.name_patterns)

    def get_target_subdirectory(self, file_path: str) -> str:
        file_time = os.path.getmtime(file_path)
        date = datetime.fromtimestamp(file_time)
        return os.path.join(self.target_dir, f"{date.year:04d}", f"{date.month:02d}")

    def process_filename(self, filename: str) -> str:
        if filename.startswith('-'):
            return filename[1:]
        return filename

    def calculate_md5(self, file_path: str) -> str:
        hash_md5 = hashlib.md5()
        with open(file_path, "rb") as f:
            for chunk in iter(lambda: f.read(4096), b""):
                hash_md5.update(chunk)
        return hash_md5.hexdigest()

    def is_duplicate(self, file_path: str) -> bool:
        md5_hash = self.calculate_md5(file_path)
        if self.redis_client.sismember('processed_files', md5_hash):
            return True
        self.redis_client.sadd('processed_files', md5_hash)
        return False

    def organize_videos(self):
        for root, _, files in os.walk(self.source_dir):
            for file in files:
                if file.startswith('.'):
                    continue

                if self.is_video_file(file) and self.matches_name_pattern(file):
                    source_path = os.path.join(root, file)

                    if self.is_duplicate(source_path):
                        print(f"Deleting duplicate file: {source_path}")
                        os.remove(source_path)
                        continue

                    target_subdir = self.get_target_subdirectory(source_path)
                    os.makedirs(target_subdir, exist_ok=True)

                    processed_filename = self.process_filename(file)
                    target_path = os.path.join(target_subdir, processed_filename)

                    if self.move_files:
                        shutil.move(source_path, target_path)
                        print(f"Moved: {source_path} -> {target_path}")
                    else:
                        shutil.copy2(source_path, target_path)
                        print(f"Copied: {source_path} -> {target_path}")


# 使用示例
if __name__ == "__main__":
    # source_directory = "/Volumes/My Passport/AAA/tmp_aaa/aaa"
    source_directory = "/Volumes/home/Photos/Moments"
    target_directory = "/Volumes/My Passport/AAA/output_web"
    name_patterns = [r"v[a-zA-Z0-9_]+0{4}[a-zA-Z0-9]+.mp4",
                     r"save_feed_[a-zA-Z0-9_-]+.mp4",
                     r"export_[0-9]+.mov"]
    video_extensions = [".mp4", ".avi", ".mkv", ".mov"]
    move_files = True  # 设置为 True 以移动文件而不是复制
    redis_host = 'localhost'
    redis_port = 6379
    redis_db = 2

    organizer = VideoFileOrganizer(source_directory, target_directory, name_patterns, video_extensions,
                                   move_files, redis_host, redis_port, redis_db)
    organizer.organize_videos()
